# class Student:
#
#     def __init__(self, name, score):
#         self.name = name
#         self.score = score
#
#     def say_score(self):
#         print("{0}的分数是{1}".format(self.name, self.score))
#
#
# s1 = Student("john", 61)
# print(s1.name, s1.score)
# s1.say_score()

# class Student:
#     school = "HNU"  # 类属性
#     count = 0  # 类属性
#
#     def __init__(self, name, score):
#         self.name = name  # 实例属性
#         self.score = score
#         Student.count = Student.count + 1
#
#     def say_score(self):  # 实例方法
#         print("我的学校是：", Student.school)
#         print("{0}的分数是{1}".format(self.name, self.score))
#
#
# s1 = Student("john", 61)  # s1是实例对象，自动调用__init__()方法
# s2 = Student("jack", 91)
# s1.say_score()
# print("一共创建了{0}个Student对象".format(Student.count))

# class Student:
#     school = "HNU"  # 类属性
#
#     @classmethod
#     def printSchool(cls):
#         print(cls.school)
#
#     @staticmethod
#     def add(a, b):  # 静态方法
#         print("{0}+{1}={2}".format(a, b, a + b))
#         return a+b
#
#
# Student.add(30, 40)
# Student.printSchool()

# 析构函数
# class Person:
#
#     def __del__(self):
#         print("销毁对象：{}".format(self))
#
#
# p1 = Person()
# p2 = Person()
# del p2
# print("程序结束")

# def f1():
#     print("f1")
#
#
# f1()  # 本质也是调用了__call__()方法
#
#
# class Car:
#
#     def __call__(self, age, money):
#         print("call方法")
#         print("车龄{0},金额{1}".format(age, money))
#
#
# c = Car()
# c(3, 20000)

# class Employee:
#     __company = "Ailibab"  # 解释器运行时把__company转化成_Employee__company
#
#     def __init__(self, name, age):
#         self.name = name
#         self.__age = age
#
#     def say_company(self):
#         print("我的公司名字是：", Employee.__company)
#         print("我的年龄是：", self.__age)
#
#     def __work(self):  # 私有方法
#         print("好好工作")
#
# print(Employee._Employee__company)
# a = Employee("haha", 20)
# a.say_company()
# print(a._Employee__age)  # 调用私有属性
# a._Employee__work()     # 调用私有方法

# class Employee:
#
#     def __init__(self, name, salary):
#         self.name = name
#         self.__salary = salary
#
#     @property
#     def salary(self):
#         print("薪资是：", self.__salary)
#         return self.__salary
#
#     @salary.setter
#     def salary(self, salary):
#         if 0 < salary < 100000:
#             self.__salary = salary
#         else:
#             print("薪资录入错误！只能在0-100000之间")
#
#
# emp1 = Employee("john", 20000)
# emp1.salary = 50000
# print(emp1.salary)
#
# emp1.salary = 100000000
# print(emp1.salary)

# class Person:
#
#     def __init__(self, name, age):
#         print("创建Person")
#         self.name = name
#         self.age = age
#
#     def say_age(self):
#         print("{0}的年龄是{1}".format(self.name, self.age))
#
#     def say_name(self):
#         print("我的名字是：", self.name)
#
#
# class Student(Person):
#
#     def __init__(self, name, age, score):
#         Person.__init__(self, name, age)
#         print("创建Student")
#         self.score = score
#
#     def say_score(self):
#         print("我的分数：", self.score)
#
#     def say_name(self):   # 重写父类的方法
#         print("hello ,my name is ", self.name)
#
#
# s1 = Student("haha", 20, 90)
# s1.say_age()
# s1.say_score()
# s1.say_name()
# print(dir(s1))

# class A:
#     pass
#
#
# class B(A):
#     pass
#
#
# class C(B):
#     pass
#
#
# print(C.mro())

# class Person:
#
#     def __init__(self, name, age):
#         print("创建Person")
#         self.name = name
#         self.age = age
#
#     def say_age(self):
#         print("{0}的年龄是{1}".format(self.name, self.age))
#
#
# # 快捷键 Alt+ 7 打开模块结构
# obj = object()
# print(dir(obj))
#
# s2 = Person("haha", 20)
# print(dir(s2))
# # 方法的本质也是是属性
# print(s2.say_age)
# print(type(s2.say_age))

# class Person:
#
#     def __init__(self, name, age):
#         self.name = name
#         self.age = age
#
#     def __str__(self):
#         """将对象转化成一个字符串描述，一般用于print方法"""
#         print("重写str方法")
#         return "名字是：{0}，年龄是{1}".format(self.name, self.age)
#
#
# p = Person("haha", 20)
# print(p)
# s = str(p)

# class Animal:
#     def shout(self):
#         print("动物叫了一声")
#
#
# class Dog(Animal):
#     def shout(self):
#         print("小狗叫了一声")
#
#
# class Cat(Animal):
#     def shout(self):
#         print("小猫叫了一声")
#
#
# def animalShout(a):
#     a.shout()  # 会产生多态，传入对象不同，则调用方法不同
#
#
# animalShout(Dog())
# animalShout(Cat())

# 工厂模式实现
# class Benz: pass
# class BMW: pass
# class BYD: pass
#
#
# class CarFactory:
#     def createCar(self, brand):
#         if brand == "宝马":
#             return BMW()
#         elif brand == "奔驰":
#             return Benz()
#         elif brand == "比亚迪":
#             return BYD()
#         else:
#             return "未知品牌，无法创建"
#
#
# factory = CarFactory()
# c1 = factory.createCar("奔驰")
# c2 = factory.createCar("宝马")
# print(c1)
# print(c2)


# 单例模式实现
# class MySingleton:
#     __obj = None
#     __init_flag = True
#
#     def __new__(cls, *args, **kwargs):
#         if cls.__obj is None:
#             cls.__obj = object.__new__(cls)
#         return cls.__obj
#
#     def __init__(self, name):
#         if MySingleton.__init_flag:
#             print("初始化第一个对象...")
#             self.name = name
#             MySingleton.__init_flag = False
#
#
# a = MySingleton("aa")
# print(a)
# b = MySingleton("bb")
# print(b)

# 工厂和单例模式结合
class CarFactory:
    __obj = None
    __init_flag = True

    def __new__(cls, *args, **kwargs):
        if cls.__obj is None:
            cls.__obj = object.__new__(cls)
        return cls.__obj

    def __init__(self):
        if CarFactory.__init_flag:
            print("初始化第一个对象...")
            CarFactory.__init_flag = False

    def createCar(self, brand):
        if brand == "宝马":
            return BMW()
        elif brand == "奔驰":
            return Benz()
        elif brand == "比亚迪":
            return BYD()
        else:
            return "未知品牌，无法创建"


class Benz:
    pass


class BMW:
    pass


class BYD:
    pass


factory = CarFactory()
c1 = factory.createCar("奔驰")
c2 = factory.createCar("宝马")
print(c1)
print(c2)
factory2 = CarFactory()
print(factory)
print(factory2)
